package fr.bugtracker.bean.administration.systeme;

import java.io.File;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.io.IOUtils;

import fr.bugtracker.bean.AbstractBean;
import fr.bugtracker.commun.dto.log.DtoFichierLog;
import fr.bugtracker.commun.dto.log.DtoLigneLog;
import fr.bugtracker.commun.enumeration.EnumParametreApplication;
import fr.bugtracker.commun.outils.UtilsJsf;
import fr.bugtracker.commun.outils.UtilsLogger;

/**
 * Bean pour l'affichage des logs
 * @author Laurent
 * @version 0.1
 */
@ManagedBean
@ViewScoped
public class BeanAfficherLogs extends AbstractBean {

	/**
	 * le pattern pour une ligne de log d'import
	 */
	private final static String PATTERN_LOG_IMPORT = "([0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}) - ([A-Z]{0,5}) - (" + UtilsLogger.SYMBOLE_TITRE + " ){0,1}(.*)";
	/**
	 * la liste des fichiers de logs
	 */
	private List<File> listeLogs = new ArrayList<File>();
	/**
	 * le fichier de logs a afficher
	 */
	private DtoFichierLog fichierLog;

	/**
	 * Constructeur de la classe <code>BeanAfficherLogs</code>.
	 */
	public BeanAfficherLogs() {
	}

	/**
	 * Méthode d'initialisation du bean
	 */
	@Override
	public void initialisation() {
		// TODO : BDD
		File dossierLogs = new File(UtilsJsf.getBeanApplication().getMapParametre().get(EnumParametreApplication.dossier_fichier) + "/logs");
		if (dossierLogs.exists()) {
			for (File fichier : dossierLogs.listFiles()) {
				if (fichier.getName().contains(".log")) {
					listeLogs.add(fichier);
				}
			}
			for (File fichier : new File(System.getProperty("com.sun.aas.instanceRoot") + "/logs").listFiles()) {
				if (fichier.getName().contains(".log")) {
					listeLogs.add(fichier);
				}
			}
		} else {
			// TODO : PROPERTIES
			UtilsJsf.addMessage(FacesMessage.SEVERITY_ERROR, "dossier inexistant");
		}
	}

	/**
	 * Retourne les differentes lignes du fichier de log d'import
	 * @param fichier {@link File}
	 */
	public void lireFichier(File fichier) {
		RandomAccessFile accessFile = null;
		try {
			fichierLog = new DtoFichierLog();
			fichierLog.setNom(fichier.getName());
			accessFile = new RandomAccessFile(fichier, "r");
			String ligne = null;
			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
			Pattern pattern = Pattern.compile(PATTERN_LOG_IMPORT);
			while ((ligne = accessFile.readLine()) != null) {
				Matcher match = pattern.matcher(ligne);
				if (match.matches()) {
					boolean titre = false;
					if (org.apache.commons.lang3.StringUtils.isNotBlank(match.group(3))) {
						titre = true;
					}
					fichierLog.getListeLigne().add(new DtoLigneLog(sdf.parse(match.group(1)), match.group(2), StringUtils.newStringUtf8(match.group(4).getBytes()), titre));
				} else {
					fichierLog.getListeLigne().add(new DtoLigneLog(null, null, StringUtils.newStringUtf8(ligne.getBytes()), false));
				}
			}
		} catch (Exception e) {
			UtilsJsf.addMessage(FacesMessage.SEVERITY_ERROR, e.getMessage());
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(accessFile);
		}
	}

	/**
	 * <p><b>Accès en lecture à l'attribut listeLogs.</b></p>
	 * @return Retourne l'attribut listeLogs sous forme de <code>List<File></code>.
	 */
	public List<File> getListeLogs() {
		return this.listeLogs;
	}

	/**
	 * <p><b>Accès en écriture à l'attribut listeLogs.</b></p>
	 * @param listeLogs L'attribut listeLogs à modifier.
	 */
	public void setListeLogs(List<File> listeLogs) {
		this.listeLogs = listeLogs;
	}

	/**
	 * <p><b>Accès en lecture à l'attribut fichierLog.</b></p>
	 * @return Retourne l'attribut fichierLog sous forme de <code>DtoFichierLog</code>.
	 */
	public DtoFichierLog getFichierLog() {
		return this.fichierLog;
	}

	/**
	 * <p><b>Accès en écriture à l'attribut fichierLog.</b></p>
	 * @param fichierLog L'attribut fichierLog à modifier.
	 */
	public void setFichierLog(DtoFichierLog fichierLog) {
		this.fichierLog = fichierLog;
	}

}
